#!/usr/bin/env python
# encoding: utf-8
"""
@author:zwb
@file: comments.py
@contact: zwb15083976291@163.com
@time: 2022/03/10
"""
from django.db.models import Q
from django.utils.decorators import method_decorator

from admin.serializers.comments import CommentsPaginatorSerializer, CommentsSerializers, DelCommentsSerializers, \
    DelListCommentsSerializers, PostCommentsSerializers
from common.models import BlogComments, BlogArticle, BlogUser
from utils.filters.views_filters import SearchCommentsFilter
from utils.responses import CommonResponse, CommonAPIResponseStatus
from utils.user_authentication import allow_admin_user
from utils.views import BasePaginateGenericAPIView, BaseGenericAPIView
from django.db import transaction


class DeleteCommentsMixin:
    def delete_comments(self, comments_id):
        # 将其相关的子评论一并删除,并修改对应的文章的评论数量
        with transaction.atomic():
            comments_list = BlogComments.objects.filter(Q(id=comments_id) | Q(father_id=comments_id)).all()
            articles_ids = [item.article_id for item in comments_list if item.article_id]
            # 修改文章的评论数量
            if articles_ids:
                articles = BlogArticle.objects.filter(id=articles_ids[0]).first()
                if articles:
                    articles.comment_count -= len(articles_ids)
                    articles.save()
            for comments in comments_list:
                comments.delete()

    def delete_comments_list(self, comments_ids):
        with transaction.atomic():
            for comments_id in comments_ids:
                comments_list = BlogComments.objects.filter(Q(id=comments_id) | Q(father_id=comments_id)).all()
                articles_ids = [item.article_id for item in comments_list if item.article_id]
                # 修改文章的评论数量
                if articles_ids:
                    articles = BlogArticle.objects.filter(id=articles_ids[0]).first()
                    if articles:
                        articles.comment_count -= len(articles_ids)
                        articles.save()
                for comments in comments_list:
                    comments.delete()


@method_decorator(allow_admin_user, name='dispatch')
class CommentsView(BasePaginateGenericAPIView, DeleteCommentsMixin):
    diff_methods_serializer_class = dict(get=CommentsPaginatorSerializer,
                                         delete=DelCommentsSerializers,
                                         post=PostCommentsSerializers
                                         )
    diff_methods_request_params = dict(
        get=dict(required=['comments_type'], optional=['pageNum', 'pageSize', 'search'],
                 defualt_value=dict(pageNum=1, pageSize=10)),
        delete=dict(required=['id']),
        post=dict(required=['id', 'content'])
    )

    filter_backends = [SearchCommentsFilter]

    def get(self, request):
        ret, msg = self.validate_request_params()
        if not ret:
            return CommonResponse(CommonAPIResponseStatus.BAD_REQUEST, message=msg)
        query_set = BlogComments.objects.filter(
            comments_type=self.serializer.validated_data.get('comments_type')).order_by(
            '-create_time')
        query_set = self.filter_queryset(query_set)
        paginator, models = self.paginate_queryset(query_set, self.serializer.validated_data)
        return CommonResponse(data=self.get_paginated_response(self.serializer.validated_data, paginator,
                                                               CommentsSerializers(instance=models, many=True).data))

    def delete(self, request):
        ret, msg = self.validate_request_params()
        if not ret:
            return CommonResponse(CommonAPIResponseStatus.BAD_REQUEST, message=msg)
        # 删除评论
        self.delete_comments(self.serializer.validated_data.get("id"))

        return CommonResponse(message="删除评论成功")

    def post(self, request):
        # 评论回复
        ret, msg = self.validate_request_params()
        if not ret:
            return CommonResponse(CommonAPIResponseStatus.BAD_REQUEST, message=msg)
        self.add_comments()
        return CommonResponse(message="回复成功")

    def add_comments(self):
        comments_id = self.serializer.validated_data.get('id')
        father_comments = BlogComments.objects.filter(id=comments_id).first()
        # 获取到博主信息
        admin = BlogUser.objects.first()
        comments_data = dict()
        comments_data['name'] = admin.username
        comments_data['email'] = admin.email
        comments_data['title_image'] = admin.user_image_url
        comments_data['is_master'] = 1
        comments_data['comments_type'] = father_comments.comments_type
        comments_data['content'] = self.serializer.validated_data.get('content')
        comments_data['article_id'] = father_comments.article_id
        comments_data['article_name'] = father_comments.article_name
        if father_comments.father_id:
            comments_data['father_id'] = father_comments.father_id
            comments_data['reply_id'] = father_comments.id
            comments_data['reply_name'] = father_comments.name
        else:
            comments_data['father_id'] = father_comments.id

        with transaction.atomic():
            BlogComments.objects.create(**comments_data)
            if comments_data['article_id']:
                articles = BlogArticle.objects.filter(id=comments_data['article_id']).first()
                articles.comment_count += 1
                articles.save()


@method_decorator(allow_admin_user, name='dispatch')
class CommentsListView(BaseGenericAPIView, DeleteCommentsMixin):
    diff_methods_serializer_class = dict(delete=DelListCommentsSerializers)

    diff_methods_request_params = dict(delete=dict(required=['ids']))

    def delete(self, request):
        ret, msg = self.validate_request_params()
        if not ret:
            return CommonResponse(CommonAPIResponseStatus.BAD_REQUEST, message=msg)
        # 删除评论
        self.delete_comments_list(self.serializer.validated_data.get("ids"))
        return CommonResponse(message="批量删除评论成功")
